﻿using System;
using System.Collections.Generic;
using WindowsGame;
using WindowsGame.Static;
using WindowsGame.Library.Data;
using WindowsGame.Library.IoC;
using WindowsGame.Tests.Data;
using NUnit.Framework;

namespace WindowsGame.Tests
{
	[TestFixture]
	public class FileManagerTests
	{
		// System under test.
		private IFileManager fileManager;

		private Level level;
		private IList<String> levelIndexes;
		private int numberOfLevels;

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			IoCContainer.Initialize<IFileProxy, TestFileProxy>();
			IoCContainer.Initialize<IFileManager, FileManager>();
		}

		[SetUp]
		public void SetUp()
		{
			fileManager = IoCContainer.Resolve<IFileManager>();
		}

		[Test]
		public void LevelDataValidateTest()
		{
			String levelsFile = GetPath("LevelData.txt");
			levelIndexes = fileManager.LoadTxt(levelsFile);
			numberOfLevels = levelIndexes.Count;

			// There must be at least one level!
			Assert.IsTrue(numberOfLevels > 0);

			for (Int32 levelIndex = 0; levelIndex < numberOfLevels; ++levelIndex)
			{
				String levelFile = levelIndexes[levelIndex];
				Validate(levelFile, levelIndex);
			}
		}

		[Test]
		[ExpectedException(typeof(Exception))]
		public void LevelFileValidateNullTest()
		{
			level = new Level(null);
			level.Validate();
		}

		[Test]
		[ExpectedException(typeof(Exception))]
		public void LevelFileValidateLineLengthTest()
		{
			Validate("555");
		}

		[Test]
		[ExpectedException(typeof(NotSupportedException))]
		public void LevelFileValidateCharacterTest()
		{
			Validate("666");
		}

		[Test]
		[ExpectedException(typeof(NotSupportedException))]
		public void LevelFileValidatePlayerTest()
		{
			Validate("777");
		}

		[Test]
		[ExpectedException(typeof(NotSupportedException))]
		public void LevelFileValidateExitTest()
		{
			Validate("888");
		}

		[Test]
		[ExpectedException(typeof(NotSupportedException))]
		public void LevelFileValidateImpossibleTest()
		{
			Validate("999");
		}

		private void Validate(String levelFile)
		{
			Validate(levelFile, 0);
		}
		private void Validate(String levelFile, Int32 levelIndex)
		{
			String levelPath = GetPath(Constants.LEVELS_DIRECTORY, levelFile + ".txt");
			IList<String> levelData = fileManager.LoadTxt(levelPath);
			level = new Level(levelData);
			level.Validate();

			String text = String.Format("Level #{0} = {1}.txt [{2} rows]", (levelIndex + 1), levelFile, levelData.Count);
			Console.WriteLine(text);
		}

		private static String GetPath(String name)
		{
			return GetPath(Constants.DATA_DIRECTORY, name);
		}
		private static String GetPath(String fldr, String name)
		{
			String path = String.Format("{0}/{1}/{2}", Constants.ROOT_DIRECTORY, fldr, name);
			String root = @"..\..\..\..\WindowsGame\WindowsGame\bin\x86\Debug\";

			return root + path;
		}


		[TestFixtureTearDown]
		public void TestFixtureTearDown()
		{
			IoCContainer.Release();
		}
	}
}